package com.vlad.domen.waiters;

import java.util.Date;
import java.util.Queue;
import java.util.concurrent.TimeUnit;

import com.vlad.domen.Restaurant;
import com.vlad.domen.chefs.ChefTeam;
import com.vlad.domen.util.Logger;
import com.vlad.domen.util.Order;
import com.vlad.domen.util.Status;

public class Waiter implements Runnable {
	private int id;
	private Restaurant restaurant;

	private Status status;

	public Waiter() {
	}

	public Waiter(int id, Restaurant restaurant) {
		super();
		this.id = id;
		this.restaurant = restaurant;
		status = Status.IDLE;
	}

	public synchronized int getId() {
		return id;
	}

	public synchronized Status getStatus() {
		return status;
	}

	@Override
	public void run() {
		Order order = null;
		WaiterTeam waiterTeam = restaurant.getWaiterTeam();
		Queue<Order> orders = waiterTeam.getOrders();
		while (!Thread.interrupted()) {
			synchronized (this) {
				try {
					Logger.logWrite("" + new Date() + " " + this
							+ " waiting for orders" + "\n");

					while (orders.isEmpty()) {
						wait();
					}
					Thread.yield();
					synchronized (orders) {
						if (!orders.isEmpty()) {
							order = orders.poll();
							status = Status.WORKING;
						}
					}
				} catch (InterruptedException e) {
					return;
				}
			}

			Logger.logWrite("" + new Date() + " " + this + " picked up order "
					+ order.getId() + "\n");
			try {
				TimeUnit.MILLISECONDS.sleep(100);
			} catch (InterruptedException e) {
				return;
			}
			order.setWaiter(this);
			ChefTeam chefTeam = restaurant.getChefTeam();
			chefTeam.takeOrder(order);
			Logger.logWrite("" + new Date() + " " + this + " sent order "
					+ order.getId() + "to chefs, waiting ..." + "\n");
			synchronized (this) {
				try {
					wait();
				} catch (InterruptedException e) {
					return;
				}
			}
			Logger.logWrite("" + new Date() + " " + this
					+ " got and sent order " + order.getId() + " " + " for "
					+ order.getConsumer() + "\n");
			synchronized (order.getConsumer()) {
				order.getConsumer().notify();
			}
			status = Status.IDLE;
		}
	}

	public synchronized void setId(int id) {
		this.id = id;
	}

	@Override
	public synchronized String toString() {
		return "Waiter " + getId();
	}
}
